using System;
using System.Collections.Generic;
using System.Text;
using Lizk.SimpleHUD;
using System.Data;
using Lizk.WebScraper;
using System.IO;
using System.Linq;
using SharpMedia.Controls;
using MediaData;

namespace SharpMedia.Pages
{
    public class MovieInfoPage : MediaPage
    {
        HUDImage titleImage, imgRating, playButton;
        HUDLabel lblTitle, lblRating, lblPlay, lblWeb;
        ScraperIcon scraperImage;
        ScraperResult scrapedInfo;
        HUDContainerSimple options, scrollablePane;
        HUDLabel summary, cast, castTitle;
        float yOffset = 0;
        float scrolledAmount = 0f;


        private MediaDataSet.TitlesRow title;

        public MediaDataSet.TitlesRow Title
        {
            get { return title; }
            set { title = value; }
        }


        public MovieInfoPage(HUDPage parent, MediaDataSet.TitlesRow title)
            : base(parent)
        {
            this.title = title;
            this.scrapedInfo = SharpMedia.ScraperCache.GetResult(title);
            InitializeComponents();

        }


        public override void Show()
        {
            Fade(255, 6f);
            base.Show();
        }
        public override void Close()
        {
            Fade(0, 6f); 
            base.Close();
        }

        protected override void MediaChanged(MediaDataSet changes)
        {
            if (title.RowState == DataRowState.Deleted)
            {
                SharpMedia.Back();
                return;
            }

     

                this.scrapedInfo = SharpMedia.ScraperCache.GetResult(title);

                titleImage.File = SharpMedia.ImageCache.TryGetImagePath(title, "film.png");

                string titleString = title.Name;
                if (scrapedInfo != null && scrapedInfo.Year > 0)
                    titleString += " (" + scrapedInfo.Year + ")";

                lblTitle.Text= titleString;
                imgRating.Visible = scrapedInfo != null && scrapedInfo.Rating != 0;
                lblRating.Text = scrapedInfo != null && scrapedInfo.Rating != 0 ? scrapedInfo.Rating + "/10" : "";
                lblRating.Visible = scrapedInfo != null && scrapedInfo.Rating != 0;


                scrollablePane.Clear();
                scrollablePane.Add(MakeScrollableInfo());

            
        }

        public override void Deactivate()
        {
            Fade(0, 1f);
            base.Deactivate();
        }

        public override void Activate()
        {
            Fade(255, 10f);
            base.Activate();
        }


        private void InitializeComponents()
        {
            titleImage = new HUDImage(SharpMedia.ImageCache.TryGetImagePath(title, "film.png"));
            titleImage.Bounds = new RectangleS(Bounds.Width - 320, 80, 300, 400);
            titleImage.Anchor = Anchor.Right | Anchor.Top;
            Add(titleImage);

            string titleString = title.Name;
            if (scrapedInfo != null && scrapedInfo.Year > 0)
                titleString += " (" + scrapedInfo.Year + ")";

            lblTitle = new HUDLabel(titleString, "tahoma50b");
            lblTitle.Bounds = new RectangleS(170, 10, Bounds.Width - 370, 55);
            lblTitle.Anchor = Anchor.Top | Anchor.Left | Anchor.Right;
            Add(lblTitle);


            imgRating = new HUDImage("ratingstar.png");
            imgRating.Bounds = new RectangleS(Bounds.Right - 60, lblTitle.Bounds.Top + 2, 53, 53);
            imgRating.Anchor = Anchor.Right | Anchor.Top;
            imgRating.Visible = scrapedInfo != null && scrapedInfo.Rating != 0;
            Add(imgRating);

            lblRating = new HUDLabel(scrapedInfo != null && scrapedInfo.Rating != 0 ? scrapedInfo.Rating + "/10" : "", "tahoma50b");
            lblRating.Bounds = new RectangleS(Bounds.Right - 240, lblTitle.Bounds.Top, 175, 55);
            lblRating.Anchor = Anchor.Right | Anchor.Top;
            lblRating.Alignment = Alignment.Right;
            lblRating.Visible  =scrapedInfo != null && scrapedInfo.Rating != 0;
            Add(lblRating);

            scrollablePane = new HUDContainerSimple();
            scrollablePane.Bounds = new RectangleS(170, lblTitle.Bounds.Bottom + 20, titleImage.Bounds.Left - 180, Bounds.Height - lblTitle.Bounds.Bottom - 110);
            scrollablePane.Anchor = Anchor.All;
            scrollablePane.Add(MakeScrollableInfo());
            Add(scrollablePane);
            
            options = new HUDContainerSimple();
            Add(options);

            playButton = new HUDImage("pb_play140.png");
            playButton.Alpha = 175;
            playButton.OnMouseUp += new EventHandler<MouseEventArgs>(delegate { Command(HUDCommands.Select, null); });
            playButton.OnMouseEnter += new EventHandler<MouseEventArgs>(playButton_OnMouseEnter);
            playButton.OnMouseExit += new EventHandler<MouseEventArgs>(playButton_OnMouseExit);
            options.Add(playButton);

/*            webButton = new HUDImage("webbutton.png");
            options.Add(webButton);*/

            lblPlay = new HUDLabel("Start movie", "tahoma30b");
            lblPlay.Alignment = Alignment.Left | Alignment.VCenter;

            options.Add(lblPlay);

            lblWeb = new HUDLabel("Check web for info", "tahoma30b");
            lblWeb.Alignment = Alignment.Left | Alignment.VCenter;
            options.Add(lblWeb);

            scraperImage = new ScraperIcon(title, "webbutton.png");
            //scraperImage.Bounds = new RectangleS(titleImage.Bounds.Right - 40, titleImage.Bounds.Bottom - 40, 32, 32);
            scraperImage.Alpha = 175;
            scraperImage.OnMouseUp += new EventHandler<MouseEventArgs>(delegate { Command(HUDCommands.Web, null); });
            scraperImage.OnMouseEnter += new EventHandler<MouseEventArgs>(playButton_OnMouseEnter);
            scraperImage.OnMouseExit += new EventHandler<MouseEventArgs>(playButton_OnMouseExit);
            scraperImage.Anchor = Anchor.Top | Anchor.Right;
            options.Add(scraperImage);

            
            AdjustOptions();
        }

        void playButton_OnMouseExit(object sender, HUDControl.MouseEventArgs e)
        {
            HUDControl c = sender as HUDControl;
            c.Fade(175, 6f);
        }

        void playButton_OnMouseEnter(object sender, HUDControl.MouseEventArgs e)
        {
            HUDControl c = sender as HUDControl;
            c.Fade(255, 6f);
        }



        private HUDContainer MakeScrollableInfo()
        {
            yOffset = 0;
            List<string> joinSag = new List<string>();
            HUDContainerSimple container = new HUDContainerSimple();
            container.Anchor = Anchor.All ^ Anchor.Bottom;
            if (scrapedInfo == null)
            {
                HUDLabel lblDescription = new HUDLabel(!string.IsNullOrEmpty(title.Description) ? title.Description : "No information available", "tahoma20b");
                container.Size = scrollablePane.Size; 
                lblDescription.Size = container.Size;
                container.Add(lblDescription);
                
                return container;
            }

            if (scrapedInfo.Genres.Count > 0)
            {
                container.Add(new HUDLabel("Genres:", "tahoma23b")
                {
                    Bounds = new RectangleS(0, yOffset, scrollablePane.Size.Width, 25),
                                        WordBreak = false

                });

                yOffset += 25;

                container.Add(new HUDLabel(string.Join(", ", scrapedInfo.Genres.ToArray()), "tahoma20b")
                {
                    Bounds = new RectangleS(30, yOffset, scrollablePane.Size.Width - 30, 25),
                    WordBreak = false
                });

                yOffset += 25;
            }

            foreach (Person director in scrapedInfo.People.FindAll(GetDirectors))
            {
                joinSag.Add(director.Name);
            }

            if (joinSag.Count > 0)
            {
                container.Add(new HUDLabel((joinSag.Count > 1 ? "Directors: " : "Director: "), "tahoma23b")
                {
                    Bounds = new RectangleS(0, yOffset, scrollablePane.Size.Width, 25),
                    WordBreak = false
                });

                yOffset += 25;

                container.Add(new HUDLabel(string.Join(", ", joinSag.ToArray()), "tahoma20b")
                {
                    Bounds = new RectangleS(30, yOffset, scrollablePane.Size.Width - 30, 25),
                    WordBreak = false
                });

                yOffset += 25;

                joinSag.Clear();

            }

            foreach (Person writer in scrapedInfo.People.FindAll(GetWriters))
            {
                joinSag.Add(writer.Name);
            }

            if (joinSag.Count > 0)
            {
                container.Add(new HUDLabel((joinSag.Count > 1 ? "Writers: " : "Writer: "), "tahoma23b")
                {
                    Bounds = new RectangleS(0, yOffset, scrollablePane.Size.Width, 28),
                    WordBreak = false
                });

                yOffset += 28;

                container.Add(new HUDLabel(string.Join(", ", joinSag.ToArray()), "tahoma20b")
                {
                    Bounds = new RectangleS(30, yOffset, scrollablePane.Size.Width - 30, 25),
                    WordBreak = false
                });

                yOffset += 25;

                joinSag.Clear();

            }


            if (scrapedInfo.Runtime != TimeSpan.Zero)
            {
                container.Add(new HUDLabel("Runtime:", "tahoma23b")
                {
                    Bounds = new RectangleS(0, yOffset, scrollablePane.Size.Width, 28),
                    WordBreak = false

                });

                container.Add(new HUDLabel(((int)scrapedInfo.Runtime.TotalMinutes) + " minutes", "tahoma20b")
                {
                    Bounds = new RectangleS(100, yOffset, scrollablePane.Size.Width - 100, 28),
                    Alignment = Alignment.Left | Alignment.VCenter,
                    WordBreak = false
                });

                yOffset += 28;
            }

            if (!string.IsNullOrEmpty(scrapedInfo.TagLine))
            {
                container.Add(new HUDLabel("Tagline:", "tahoma23b")
                {
                    Bounds = new RectangleS(0, yOffset, scrollablePane.Size.Width, 28),
                    WordBreak = false

                });
                container.Add(new HUDLabel(scrapedInfo.TagLine, "tahoma20b")
                {
                    Bounds = new RectangleS(100, yOffset, scrollablePane.Size.Width - 100, 28),
                    Alignment = Alignment.Left | Alignment.VCenter,
                    WordBreak = false
                });

                yOffset += 28;
            }

            if (!string.IsNullOrEmpty(scrapedInfo.Summary))
            {
                container.Add(new HUDLabel("Plot Outline:", "tahoma23b")
                {
                    Bounds = new RectangleS(0, yOffset, scrollablePane.Size.Width, 28),
                    WordBreak = false

                });

                yOffset += 28;

                summary = new HUDLabel(scrapedInfo.Summary, "tahoma20b")
                {
                    Bounds = new RectangleS(30, yOffset, scrollablePane.Size.Width - 30, 25),
                    WordBreak = true
                };

                container.Add(summary);
            }
            string actors = GetActorList();
            if (!string.IsNullOrEmpty(actors))
            {
                castTitle = new HUDLabel("Cast:", "tahoma23b")
                {
                    Bounds = new RectangleS(0, yOffset, scrollablePane.Size.Width, 28),
                    WordBreak = false

                };
                container.Add(castTitle);

                cast = new HUDLabel(actors, "tahoma14b")
                {
                    Bounds = new RectangleS(30, yOffset + 28, scrollablePane.Size.Width - 30, 25)
                };

                container.Add(cast);
            }



            /*string info = TitleInfoString();
            lblDescription = new HUDLabel(!string.IsNullOrEmpty(info) ? info : "No information available", "tahoma20b");
            lblDescription.Size = container.Size;
            container.Add(lblDescription);*/


            container.Size = new SizeS(scrollablePane.Size.Width, yOffset);

            

            return container;
        }

        public override void Update(TimeSpan ts)
        {
            base.Update(ts);
            if (summary != null && summary.SourceRectangle != RectangleS.Empty)
            {
                float bottom = 0;
                foreach (var s in HUDFont.GetFont(summary.Font).TextBox2(new RectangleS(summary.CharacterOffset, new SizeS(summary.Size.Width, 100000)), summary.Color, summary.Alignment, summary.WordBreak, summary.Text))
                {
                    bottom = Math.Max(bottom, s.Destination.Bottom);
                }

                summary.Size = new SizeS(summary.Parent.Size.Width -30, bottom);

                summary.Parent.Size = new SizeS(summary.Parent.Size.Width, yOffset + summary.Bounds.Height);

                if (cast != null && cast.SourceRectangle != RectangleS.Empty)
                {
                    bottom = 0;
                    foreach (var s in HUDFont.GetFont(cast.Font).TextBox2(new RectangleS(cast.CharacterOffset, new SizeS(cast.Size.Width, 100000)), cast.Color, cast.Alignment, cast.WordBreak, cast.Text))
                    {
                        bottom = Math.Max(bottom, s.Destination.Bottom);
                    }

                    cast.Size = new SizeS(cast.Parent.Size.Width - 30, bottom);
                    castTitle.Location = new PointS(0, summary.Bounds.Bottom + 2);
                    cast.Location = new PointS(30, castTitle.Bounds.Bottom);
                    summary.Parent.Size += new SizeS(0, cast.Bounds.Bottom - summary.Bounds.Bottom);
                }
                

            }

        }

        private string TitleInfoString()
        {
            if (scrapedInfo == null)
                return title["description"].ToString();

            List<string> output = new List<string>();
            List<string> joinSag = new List<string>();

            if (scrapedInfo.Genres.Count > 0)
            {
                output.Add("Genres: " + string.Join(", ", scrapedInfo.Genres.ToArray()));
            }

            foreach (Person director in scrapedInfo.People.FindAll(GetDirectors))
            {
                joinSag.Add(director.Name);
            }

            if (joinSag.Count > 0)
                output.Add((joinSag.Count > 1 ? "Directors: " : "Director: ") + string.Join(", ", joinSag.ToArray()));

            joinSag.Clear();

            foreach (Person writer in scrapedInfo.People.FindAll(GetWriters))
            {
                joinSag.Add(writer.Name);
            }

            if (joinSag.Count > 0)
                output.Add((joinSag.Count > 1 ? "Writers: " : "Writer: ") + string.Join(", ", joinSag.ToArray()));

            if (scrapedInfo.Runtime != TimeSpan.Zero)
                output.Add("Runtime: " + ((int)scrapedInfo.Runtime.TotalMinutes) + " minutes");

            if (!string.IsNullOrEmpty(scrapedInfo.TagLine))
                output.Add("Tagline: \n" + scrapedInfo.TagLine);

            if (!string.IsNullOrEmpty(scrapedInfo.Summary))
                output.Add("Plot Outline: \n" + scrapedInfo.Summary);

            return string.Join("\n\n", output.ToArray());

        }



        private void AdjustOptions()
        {
            if (options == null)
                return;
            options.Bounds = new RectangleS(lblTitle.Bounds.Left, Bounds.Height - 80, titleImage.Bounds.Left - lblTitle.Bounds.Left, 80);
            playButton.Bounds = new RectangleS(0, 5, 70, 70);
            scraperImage.Bounds = new RectangleS(options.Bounds.Width / 2f - 35, 5, 70, 70);
            lblPlay.Bounds = new RectangleS(playButton.Bounds.Right + 4, playButton.Bounds.Top, options.Bounds.Width / 2f, playButton.Bounds.Height);
            lblWeb.Bounds = new RectangleS(scraperImage.Bounds.Right + 4, scraperImage.Bounds.Top, options.Bounds.Width / 2f, scraperImage.Bounds.Height);
        }

        public override void ResizeMove(RectangleS oldRect, RectangleS newRect)
        {
            base.ResizeMove(oldRect, newRect);
            AdjustOptions();
        }

        public void PulseWebIcon(bool toggle)
        {
            scraperImage.Tag = toggle ? (object)true : null;
            scraperImage.Fade(toggle ? (byte)255 : (byte)0, 2f);
        }

        public void SetScraperIcon(ScraperHandler.ScraperStatus status)
        {
            switch (status)
            {
                case ScraperHandler.ScraperStatus.None:
                    scraperImage.Fade(255, 2f);
                    scraperImage.File = "webbutton.png";
                    lblWeb.Text = "Check web for info";
                    break;
                case ScraperHandler.ScraperStatus.InProgress:
                    scraperImage.File = "web.png";
                    scraperImage.Alpha = 0;
                    PulseWebIcon(true);
                    scraperImage.Fade(255, 2f);
                    lblWeb.Text = "Scrape in progress...";
                    break;
                case ScraperHandler.ScraperStatus.MultipleResults:
                    scraperImage.File = "important.png";
                    PulseWebIcon(false);
                    scraperImage.Fade(255, 2f);
                    lblWeb.Text = "Multiple results found";
                    break;
                case ScraperHandler.ScraperStatus.Error:
                    scraperImage.File = "error.png";
                    PulseWebIcon(false);
                    scraperImage.Fade(255, 2f);
                    lblWeb.Text = "Scrape Failed!";
                    break;
                case ScraperHandler.ScraperStatus.Done:
                    scraperImage.File = "yes.png";
                    PulseWebIcon(false);
                    scraperImage.Fade(255, 2f);
                    scraperImage.File = "webbutton.png";
                    lblWeb.Text = "Check web for info";

                    break;
                default:
                    break;
            }
        }

        void w_FadingStopped(object sender, System.EventArgs e)
        {
            if (scraperImage.Tag != null)
            {
                if (scraperImage.Alpha == 255)
                    scraperImage.Fade(100, 1f);
                else
                    scraperImage.Fade(255, 1f);
            }
        }

        private string GetChacaterList()
        {
            if (scrapedInfo == null)
                return "";

            string actors = "";

            foreach (Person p in scrapedInfo.People)
            {
                if (p.Job != "Actor")
                    continue;

                actors += "...    " + p.Role + "\n";
            }
            return actors;
        }
        
        private string GetActorList()
        {
            if (scrapedInfo == null)
                return "";

            string actors = "";

            foreach (Person p in scrapedInfo.People)
            {
                if (p.Job != "Actor")
                    continue;

                actors += p.Name + " ... " + p.Role + "\n";
            }
            return actors;
        }

        public bool GetWriters(Person p) { return p.Job == "Writer"; }
        public bool GetActors(Person p) { return p.Job == "Actor"; }
        public bool GetDirectors(Person p) { return p.Job == "Director"; }


        public override void Command(HUDCommands command, object tag)
        {
            switch (command)
            {
                case HUDCommands.Back:
                case HUDCommands.Stop:
                    SharpMedia.Back();
                    break;

                case HUDCommands.Web:
                    if (title != null)
                        Util.TryScrape(this, title); 
                    break;
                case HUDCommands.PlayPause:
                case HUDCommands.Select:
                case HUDCommands.Play:

                    var file = from f in title.GetFilesRows()
                               where SharpMedia.RootManager.IsOnline(f.Volume)
                               orderby f.Path
                               select f;

                    if (file.Count() == 0)
                        break;

                    switch (MediaUtil.GetFiletype(file.First().Path))
                    {
                        case MediaUtil.FileType.Unknown:
                            break;
                        case MediaUtil.FileType.Video:

                            VideoList vl = new VideoList();
                            for (int i = 0; i < file.Count(); i++)
                            {
                                vl.Add(new VideoSource(file.Count() > 1 ? string.Format("({0}/{1}): {2}", i + 1, file.Count(), title.Name) : title.Name, Util.GetDBFilePath(file.ElementAt(i))));
                            }

                            PlayerPage playerPage = new PlayerPage(this, vl);
                            playerPage.StopBetweenParts = false;
                            SharpMedia.Navigate(playerPage);

                            break;
                        case MediaUtil.FileType.DiscImage:


                            string path = Util.GetDBFilePath(file.First());
                            Util.MountImage(path);

                            DVDSelectionPage dsp = new DVDSelectionPage(this, SharpMedia.Settings.MountDrive);
                            SharpMedia.Navigate(dsp);
                            break;

                    }
                    break;
                case HUDCommands.Pause:
                    break;
                case HUDCommands.Forward:
                    break;
                case HUDCommands.Rewind:
                    break;
                case HUDCommands.Next:
                    break;
                case HUDCommands.Previous:
                    break;
                case HUDCommands.KeyPress:
                    break;

                case HUDCommands.Down:
                    if (scrollablePane.Count == 0 || scrollablePane[0].Size.Height < scrollablePane.Size.Height)
                        break;

                    scrolledAmount -= 50;
                    if (scrolledAmount < -(scrollablePane[0].Size.Height - scrollablePane.Size.Height))
                        scrolledAmount = -(scrollablePane[0].Size.Height - scrollablePane.Size.Height);
                    scrollablePane[0].Destination = new PointS(0, scrolledAmount);

                    break;
                case HUDCommands.Up:
                    if (scrollablePane.Count == 0)
                        break;
                    
                        scrolledAmount += 50;
                    if (scrolledAmount > 0)
                        scrolledAmount = 0;
                    scrollablePane[0].Destination = new PointS(0, scrolledAmount);
                    break;

                default:
                    if (parent != null)
                        parent.Command(command, tag);
                    break;
            }
        }
    }
}
